package com.syqc.choose.teamcar

import com.syqc.entity.CarDetail
import com.syqc.entity.TeamCars
import com.syqc.entity.TeamDetail
import com.syqc.entity.TeamsAndCars

object TeamCarsUtil {
    private val allTeams = LinkedHashMap<String, TeamDetail>()
    private val teamHierarchy = LinkedHashMap<String, ArrayList<String>>()
    private val cars = ArrayList<CarDetail>()
    private val rootTeams = ArrayList<String>()
    private val rootCars = ArrayList<CarDetail>()

    fun handlerTeamCars(teamCars: TeamCars, isVideo: Boolean) {
        clearData()
        val teamIds = buildTeamStructure(teamCars, isVideo)
        identifyRootTeams(teamCars, teamIds)
        filterCars(teamCars, isVideo, teamIds)
    }

    private fun clearData() {
        allTeams.clear()
        teamHierarchy.clear()
        cars.clear()
        rootTeams.clear()
        rootCars.clear()
    }

    private fun buildTeamStructure(teamCars: TeamCars, isVideo: Boolean): Set<String> {
        val teamIds = mutableSetOf<String>()
        teamCars.teamList.filter { !isVideo || it.videoNum > 0 }.forEach { team ->
            val teamId = team.id
            allTeams[teamId] = team
            teamHierarchy.computeIfAbsent(team.pid) { ArrayList() }.add(teamId)
            teamIds.add(teamId)
        }
        return teamIds
    }

    private fun identifyRootTeams(teamCars: TeamCars, teamIds: Set<String>) {
        teamCars.teamList.forEach { team ->
            if (!teamIds.contains(team.pid)) rootTeams.add(team.id)
        }
    }

    private fun filterCars(teamCars: TeamCars, isVideo: Boolean, teamIds: Set<String>) {
        cars.addAll(if (isVideo) teamCars.carList.filter { !it.videos.isNullOrEmpty() } else teamCars.carList)
        rootCars.addAll(cars.filter { !teamIds.contains(it.teamId) })
    }

    fun getTeamCars(teamId: String): ArrayList<TeamsAndCars> {
        val result = ArrayList<TeamsAndCars>()
        getChildIds(teamId).forEach { childId ->
            allTeams[childId]?.let { result.add(toTeamsAndCars(it)) }
        }
        addCarsToResult(teamId, result)
        return result
    }

    fun getTeams(teamId: String): ArrayList<TeamsAndCars> {
        return ArrayList(getChildIds(teamId).mapNotNull { allTeams[it]?.let(TeamCarsUtil::toTeamsAndCars) })
    }

    private fun getChildIds(teamId: String) = if (teamId == "0") rootTeams else teamHierarchy[teamId] ?: emptyList()

    private fun addCarsToResult(teamId: String, result: ArrayList<TeamsAndCars>) {
        val carList = if (teamId == "0") rootCars else cars.filter { it.teamId == teamId }
        result.addAll(carList.map(TeamCarsUtil::toTeamsAndCarsFromCar))
    }

    private fun toTeamsAndCars(team: TeamDetail) = TeamsAndCars(
        teamId = team.id,
        teamName = team.name,
        carNum = team.carNum,
        videoNum = team.videoNum,
        noAuth = team.noAuth,
        acc = team.acc,
        isTeam = true,
        offCount = team.offCount,
        onCount = team.onCount
    )

    private fun toTeamsAndCarsFromCar(car: CarDetail) = TeamsAndCars(
        carId = car.id,
        plate = car.plate,
        carName = car.name,
        iconLink = car.iconLink,
        teamName = allTeams[car.teamId]?.name ?: "",
        videos = car.videos,
        acc = car.acc
    )

    fun search(key: String): ArrayList<TeamsAndCars> {
        val allTeamList = allTeams.values.map(TeamCarsUtil::toTeamsAndCars)
        return if (key.isEmpty()) ArrayList(allTeamList) else ArrayList(allTeamList.filter { it.teamName!!.contains(key) })
    }
}